home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * $Source: /unixb/home/unixlib/source/unixlib37/src/c/RCS/strtod,v $
- * $Date: 1996/05/06 09:03:13 $
- * $Revision: 1.2 $
- * $State: Rel $
- * $Author: unixlib $
- *
- * $Log: strtod,v $
- * Revision 1.2 1996/05/06 09:03:13 unixlib
- * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
- * Saved for 3.7a release.
- *
- * Revision 1.1 1996/04/19 21:26:42 simon
- * Initial revision
- *
- ***************************************************************************/
-
- static const char rcs_id[] = "$Id: strtod,v 1.2 1996/05/06 09:03:13 unixlib Rel $";
-
- #include <ctype.h>
- #include <stdlib.h>
-
- #define MAXEXP 308 /* maximum decimal exponential for IEEE double */
-
- /* recognizes: [spaces][sign][digs][[.][digs]][[e|E][space|sign][int]] */
-
- /* this is the most efficient strtod() can be, without resorting to
- * assuming IEEE 'D' or some other floating point representation */
-
- double
- strtod (register const char *s, char **end)
- {
- register double r, p;
- register unsigned int x;
- register int r_, x_;
- const char *_s;
-
- r = 0;
- r_ = 0;
-
- if (!s)
- return (r);
-
- while (isspace (*s++));
- s--;
-
- if (*s == '-' || *s == '+')
- {
- if (*s == '-')
- r_ = 1;
- s++;
- }
-
- while (isdigit (*s))
- {
- r = r * 10 + (int) (*s - '0');
- s++;
- }
-
- if (*s != '.')
- goto integer;
-
- s++;
- p = 1;
- while (isdigit (*s))
- {
- r = r * 10 + (int) (*s - '0');
- p *= 10;
- s++;
- }
- r /= p;
-
- integer:if (!(*s == 'e' || *s == 'E'))
- goto ret;
-
- x_ = (int) strtol (++s, (char **) &_s, 0);
- s = _s;
-
- x_ = (x_ < 0) ? ((x = (unsigned int) (-x_)), 1) : ((x = (unsigned int) x_), 0);
-
- if (x > MAXEXP)
- {
- r_ = 0;
- r = 0;
- goto ret;
- }
-
- p = 1;
- while (x)
- p *= 10, x--;
- r = (x_) ? (r / p) : (r * p);
-
- ret:if (end)
- *end = (char *) s;
-
- return (r_ ? -r : r);
- }
-